﻿using rfidLink.Extend;
using RFIDReaderDll;
using smforj.common.model;
using smforj.common.service;
using smforj.common.util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;

namespace MonitorEquipmentFrm
{
    /// <summary>
    /// 馆员工作站转换，监控实现类，该对象需要app.config配置参数
    /// </summary>
    public class MonitorZDHKWorkStationImpl :IMonitor
    {
        #region 变量
        private LogManage log = new LogManage(); 

        /// <summary>
        /// client 对象
        /// </summary>
        private IMonitorClient monitorClient = null;
        /// <summary>
        /// 设备信息
        /// </summary>
        private EquementInfo equement = null;
        /// <summary>
        /// RFID读卡器对象20160520修改读卡器为中电海康设备，他们设备对动态库已经进行封装
        /// 经过讨论决定不再进行封装
        /// </summary>
        //private IRFIDReader iReader;
        private LinkageExtend link = null;
        private List<RadioInformation> radios;  

        /// <summary>
        /// 是否连接设备
        /// </summary>
        private Boolean isOpen = false;
        private Boolean isReading = false;
        /// <summary>
        /// 消息队列
        /// </summary>
        private List<String> queue = new List<String>();
        /// <summary>
        /// 初始标签信息
        /// </summary>
        private List<String> baseQueue = new List<String>();

        /// <summary>
        /// 线程阻塞
        /// </summary>
        private bool IsGetting = false;
        /// <summary>
        /// 读取数据线程
        /// </summary>
        private AutoResetEvent myResetRead = new AutoResetEvent(false);
        /// <summary>
        /// 上传数据线程
        /// </summary>
        private AutoResetEvent myResetUpload = new AutoResetEvent(false); 
         
        /// <summary>
        /// 监控线程
        /// </summary>
        Thread thread = null;
        /// <summary>
        /// 数据读取线程
        /// </summary>
        Thread threadRead = null;

       
        


        private String message = "";
        private String error = "";
        private int istatus = 0;


        /// <summary>
        /// 当前barcode
        /// </summary>
        private String curBarcode = String.Empty;
        /// <summary>
        /// 当前epc
        /// </summary>
        private String curEpc = String.Empty;

        #endregion


        public MonitorZDHKWorkStationImpl()
        {
            init();
        }
        /// <summary>
        /// 初始化参数
        /// </summary>
        public void init()
        {

        }


        
        #region 读卡器操作

        private void InitData()
        { 

        } 
        private void ClearData()
        { 
        
        
        }

        private void AutoConnect()
        {
            UpdateMessage(InfoType.Info,String.Format("启动{0}服务...",this.equement.IConnConfig.Ip));
            link = new LinkageExtend(); 
            operResult result = link.Initialization();
            link.RadioInventory += new EventHandler<RadioInventoryEventArgs>(link_RadioInventory);
            if (result == operResult.Ok) 
                radios = link.GetRadioEnumeration();  
            try
            {  
                log.Debug("radios : " + radios.Count);
                if (radios != null && radios.Count > 0)
                {
                    result = link.Connect(radios[0].radioHandle);
                    if (result == operResult.Ok)
                        isOpen = true;
                } 
                //设置天线
                //Antena(); 
                UpdateMessage(InfoType.Info, String.Format("{0}服务状态isOpen：{1}", this.equement.IConnConfig.Ip,isOpen));
            }
            catch (Exception ex)
            {
                error = String.Format("启动{0}服务异常：{1}",this.equement.IConnConfig.Ip,ex.Message);
                UpdateMessage(InfoType.Error, error);
                log.Error(error);
                isOpen = false;
                istatus = -1;
            }
            UpdateMessage(InfoType.Info, String.Format("启动{0}服务...end ", this.equement.IConnConfig.Ip));
        }

        /// <summary>
        /// 关闭设备
        /// </summary>
        private void AutoDisconnect()
        {
            UpdateMessage(InfoType.Info,String.Format("停止{0}服务...",this.equement.IConnConfig.Ip));
            try
            {  
                if (isOpen)
                {
                    isStopChecking = true;
                    isReading = false;
                    if (radios != null && radios.Count > 0)
                    {
                        operResult result = link.Disconnect(radios[0].radioHandle);
                        if (result == operResult.Ok) isOpen = false;
                    }
                    //等待数据处理线程
                    myResetRead.WaitOne(3000);
                    myResetUpload.WaitOne(3000); 
                    UpdateMessage(InfoType.Info, String.Format("{0}服务状态isOpen：{1}", this.equement.IConnConfig.Ip, isOpen));

                    if (null != threadRead) threadRead.Abort();
                    if (null != thread) thread.Abort();
                }
                istatus = 0; 
            }
            catch (Exception ex)
            {
                error = String.Format("关闭服务异常：{0}",ex.Message);
                UpdateMessage(InfoType.Error, error);
                log.Error(error);
                istatus = 1;
            }
            finally
            {
                link = null;
                radios = null;
                queue.Clear();
                //baseQueue.Clear();
                testCount = 0;
                isStopChecking = false;  
                isOpen = false; 
                GC.Collect();
            }
            UpdateMessage(InfoType.Info, String.Format("停止{0}服务...end", this.equement.IConnConfig.Ip, isOpen));
        }    
        #endregion

        #region 事件处理

        /// <summary>
        /// 
        /// 多次盘点进行一次数据校验
        /// 盘点多次读取到的标签数据进行合并，重复的去除，多余的添加
        /// </summary>
        private List<String> temp = new List<String>();
        //private int initCount = 10;
        private long testCount = 0;

        /// <summary>
        /// 盘点使用函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void link_RadioInventory(object sender, RadioInventoryEventArgs e)
        {
            //this.label_inventorySpeed.BeginInvoke((MethodInvoker)delegate()
            //{
            //    label_inventorySpeed.Text = e.inventorySpeed.ToString("0") + "tags/sec";
            //});

            //string InventoryInfo = string.Empty;
            //for (int i = 0; i < e.tagInfo.epclength; i++)
            //{
            //    InventoryInfo += String.Format("{0:X4}", e.tagInfo.epc[i]);
            //}

            //InventoryInfo += "(RSSI:" + e.tagInfo.rssi + " )";

            //this.listBox_Inventory.BeginInvoke((MethodInvoker)delegate()
            //{
            //    if (listBox_Inventory.Items.Count > 200)
            //    {
            //        listBox_Inventory.Items.Clear();
            //    }

            //    listBox_Inventory.Items.Add(InventoryInfo);
            //    listBox_Inventory.SelectedIndex = listBox_Inventory.Items.Count - 1;
            //});
        }


        #endregion

        #region 主业务方法
        private Boolean isStopChecking = false; 

        private bool ValidateHex_uint(string input, out uint value)
        {
            if (!uint.TryParse(input, NumberStyles.AllowHexSpecifier, null, out value))
            {
                return false;
            }

            return true;
        }
        /// <summary>
        /// 读取EPC信息并剔除重复数据
        /// </summary>
        /// <returns></returns>
        private List<String> ReadTag()
        { 
            List<String> list = new List<String>();
            if (link == null)
                return list;

            if (radios != null && radios.Count > 0)
            {
                ReadParms parm = new ReadParms();
                parm.memBank = rfidLink.Extend.MemoryBank.EPC;

                uint accesspassword = 0;
                ValidateHex_uint("00000000", out accesspassword);
                parm.accesspassword = accesspassword;
                parm.offset = (ushort)2;
                parm.length = (ushort)6;

                List<ReadResult> readResults; 
                operResult result = link.TagInfoRead(radios[0].radioHandle, parm, out readResults);
                if (result == operResult.Ok)
                {
                    lock (queue)
                    {
                        foreach (ReadResult readInfo in readResults)
                        {
                            if (readInfo.result == tagMemoryOpResult.Ok)
                            {
                                string rfidtemp = string.Empty;
                                for (int i = 0; i < readInfo.datalength; i++)
                                    rfidtemp += String.Format("{0:X4}", readInfo.readData[i]);
                                String book = list.Find(delegate(String _book) { return _book == rfidtemp; });
                                if (book == null)
                                    list.Add(book);
                            }

                        }
                    } 
                } 
            }  
            return list;
        }   
        /// <summary>
        /// 读取数据
        /// </summary>
        private void ReadData()
        {
            while (!isStopChecking)
            {
                if (link == null)
                    break;
                Thread.Sleep(GlobalCache.RTimeSpan);
                try
                {
                    isReading = true;
                    testCount++;  
                    temp = ReadTag();
                    DateTime date = DateTime.Now;
                    //只有一个标签时进行比对操作
                    if (temp.Count == 1)
                    {
                        String tag = temp[0];
                        //只有不一样的标签才进行处理
                        if (curEpc.ToUpper() != tag.ToUpper())
                        {
                            String com = baseQueue.Find(delegate(String _com) { return _com.ToUpper() == tag.ToUpper(); });
                            //不存在则进行其他操作
                            if (com == null) 
                                curEpc = com;  
                            //存在则不处理
                        }
                    }
                    else
                    {
                        UpdateMessage(InfoType.Info, "存在多个标签，请使用一个标签");
                    }
                    temp.Clear(); 
                }
                catch (Exception ex)
                {
                    error = "reader_OnInventoryReport异常：" + ex.Message;
                    UpdateMessage(InfoType.Error, error);
                    log.Error("reader_OnInventoryReport异常：" + ex.Message); 
                }  
            }
            isReading = false;
            myResetRead.Set();
        } 
        /// <summary>
        /// 业务处理方法
        /// </summary>
        private void CheckData()
        {
            while (!isStopChecking)
            {
                Thread.Sleep(100 * GlobalCache.UTimeSpan);
                if (!IsGetting)
                {
                    IsGetting = true;
                    try
                    { 
                        lock (queue)
                        {
                            UpdateMessage(InfoType.Info, "isReading：" + isReading + " testCount: " + testCount);

                            Info info = this.monitorClient.GetInfo();
                            if (null != info && !String.IsNullOrEmpty(curEpc))
                            {
                                if (info.message != curBarcode)
                                { 
                                    //编写RFID信息
                                

                                } 
                            } 
                        }
                    }
                    catch (Exception ex)
                    {
                        error = "处理信息异常：" + ex.Message;
                        UpdateMessage(InfoType.Error, error);
                        log.Error(error); 
                    }
                    IsGetting = false;
                } 
            }
            myResetUpload.Set();
        }


        
        private void UpdateMessage(InfoType type, String message)
        {
            if (!isStopChecking) 
                monitorClient.UpdateMessage(new Info() { message = message, type = type},this); 
        }
        #endregion

        #region public 

        public string GetError()
        {
            return error;
        }

        public int GetStatus()
        {
            return istatus;
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <returns>0 成功 其他 失败</returns>
        public int StartServer()
        {
            InitData();
            //开户安全门
            AutoConnect();
            if (isOpen)
            {
                threadRead = new Thread(new ThreadStart(ReadData));
                threadRead.Start();

                thread = new Thread(new ThreadStart(CheckData));
                thread.Start(); 
            }
            return isOpen ? 0 : -1;
        } 

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <returns></returns>
        public int StopServer()
        { 
            AutoDisconnect();
            ClearData();
            return isOpen ? -1 : 0;
        }

        public string GetMessage()
        {
            return message;
        }
        #endregion 

        /// <summary>
        /// 获取设备配置信息
        /// </summary>
        /// <returns></returns>
        public EquementInfo GetEquementInfo()
        {
            return this.equement;
        }
        /// <summary>
        /// 设置monitorClient
        /// </summary>
        /// <param name="monitorClient"></param>
        public void SetMonitorClient(IMonitorClient monitorClient)
        {
            this.monitorClient = monitorClient;
        }

        public void SetEquementInfo(EquementInfo equement)
        {
            this.equement = equement;
        } 
    }
}
